package com.cn.por.auto.service.impl;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import com.cn.por.auto.factory.CodeFactory;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.cn.por.auto.dao.AutoDAO;
import com.cn.por.auto.dto.ModelParam;
import com.cn.por.auto.entity.Table;
import com.cn.por.auto.entity.TableDetiles;
import com.cn.por.auto.factory.DataModelFactory;
import com.cn.por.auto.service.AutoService;
import com.cn.por.util.freemarker.FreeMarkerUtil;
import com.cn.por.util.freemarker.StringFormaterUtil;

import freemarker.template.TemplateException;
@Service
public class AutoServiceImpl implements AutoService{
	
	@Autowired
	private AutoDAO autoDAO;
	
	@Override
	public List<Table> getTables(String tableSchema) {
		return autoDAO.getTables(tableSchema);
	}

	@Override
	public List<TableDetiles> getTableDetiles(String tableName) {
		return autoDAO.getTableDetiles(tableName);
	}

	@Override
	public Map<String,byte[]> autoGrowMan(ModelParam modelParam) {
		List<ModelParam> list = new ArrayList<ModelParam>();
		try {
			list = getModelParamList(modelParam);
		} catch (IllegalAccessException | InvocationTargetException e1) {
			e1.printStackTrace();
		}
		Map<String,byte[]> byteArray = new HashMap<String,byte[]>();
		for(ModelParam model : list) {
			DataModelFactory factory = createInstance(model.getFactoryName());
			factory.setProperties(model);
			try {
				byte[] byteMsg = FreeMarkerUtil.dataFormateByte(factory.getDataModel());
				byteArray.put(model.getZipDir(), byteMsg);
			} catch (IOException | TemplateException e) {
				e.printStackTrace();
			}
		}
		return byteArray;
	}

	@Override
	public Map<String, byte[]> gena(ModelParam modelParam) {
		CodeFactory codeFactory = new CodeFactory();
		return codeFactory.generateCode(modelParam.getFrameworkType(), modelParam);
	}


	private List<ModelParam> getModelParamList(ModelParam modelParam) throws IllegalAccessException, InvocationTargetException{
		List<ModelParam> list = new ArrayList<ModelParam>();
		
		ModelParam mapper = new ModelParam();
		BeanUtils.copyProperties(mapper,modelParam);
		mapper.setFactoryName("com.cn.por.auto.factory.MapperDataModelFactory");
		mapper.setSuffixName("Mapper");
		mapper.setFtlName("mapper.ftl");
		mapper.setFileName(StringFormaterUtil.columnToProperty(modelParam.getTableName()) + "Mapper" +".xml");
		mapper.setZipDir("sql/"+mapper.getFileName());
		list.add(mapper);
		
		ModelParam dao = new ModelParam();
		BeanUtils.copyProperties(dao,modelParam);
		dao.setFactoryName("com.cn.por.auto.factory.InterfaceDataModelFactory");
		dao.setFtlName("interfaceDesc.ftl");
		dao.setSuffixName("Dao");
		dao.setFileName(StringFormaterUtil.columnToProperty(modelParam.getTableName()) + "Dao" +".java");
		dao.setZipDir(modelParam.getBasePackage().replace(".", "/")+"/dao/"+dao.getFileName());
		dao.setFilePath("../tps-por-biz/src/main/java/"+ modelParam.getBasePackage().replace(".", "/")+"/dao/");
		list.add(dao);
		
		ModelParam entity = new ModelParam();
		BeanUtils.copyProperties(entity,modelParam);
		entity.setFactoryName("com.cn.por.auto.factory.EntityDataModelFactory");
		entity.setFtlName("entity.ftl");
		entity.setFileName(StringFormaterUtil.columnToProperty(modelParam.getTableName()) +".java");
		entity.setZipDir(modelParam.getBasePackage().replace(".", "/")+"/entity/"+entity.getFileName());
		entity.setFilePath("../tps-por-biz/src/main/java/"+ modelParam.getBasePackage().replace(".", "/")+"/entity/");
		list.add(entity);
		
		ModelParam service = new ModelParam();
		BeanUtils.copyProperties(service,modelParam);
		service.setFactoryName("com.cn.por.auto.factory.InterfaceDataModelFactory");
		service.setFtlName("interfaceDesc.ftl");
		service.setSuffixName("Service");
		service.setFileName(StringFormaterUtil.columnToProperty(modelParam.getTableName()) + "Service"+".java");
		service.setZipDir(modelParam.getBasePackage().replace(".", "/")+"/service/"+service.getFileName());
		service.setFilePath("../tps-por-biz/src/main/java/"+ modelParam.getBasePackage().replace(".", "/")+"/service/");
		list.add(service);
		
		ModelParam serviceImpl = new ModelParam();
		BeanUtils.copyProperties(serviceImpl,modelParam);
		serviceImpl.setFactoryName("com.cn.por.auto.factory.ServiceDataModelFactory");
		serviceImpl.setFtlName("classDesc.ftl");
		serviceImpl.setSuffixName("Service.Impl");
		serviceImpl.setFileName(StringFormaterUtil.columnToProperty(modelParam.getTableName()) + "ServiceImpl"+".java");
		serviceImpl.setZipDir(modelParam.getBasePackage().replace(".", "/")+"/service/impl/"+serviceImpl.getFileName());
		serviceImpl.setFilePath("../tps-por-biz/src/main/java/"+ modelParam.getBasePackage().replace(".", "/")+"/service/impl/");
		list.add(serviceImpl);
		
		ModelParam controller = new ModelParam();
		BeanUtils.copyProperties(controller,modelParam);
		controller.setFactoryName("com.cn.por.auto.factory.ControllerDataModelFactory");
		controller.setFtlName("classDesc.ftl");
		controller.setSuffixName("Controller");
		controller.setFileName(StringFormaterUtil.columnToProperty(modelParam.getTableName()) + "Controller"+".java");
		controller.setZipDir(modelParam.getBasePackage().replace(".", "/")+"/controller/"+controller.getFileName());
		controller.setFilePath("../tps-por-biz/src/main/java/"+ modelParam.getBasePackage().replace(".", "/")+"/controller/");
		list.add(controller);
		return list;
	}
	
	private DataModelFactory createInstance(String className){
		try {
			Class clz = Class.forName(className);
			DataModelFactory obj = (DataModelFactory) clz.newInstance();
			return obj;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
}
